// TimeUtils.hpp
#pragma once

#include <chrono>
#include <iomanip>
#include <sstream>
#include <string>
#include <sys/time.h>

class TimeUtils {
  public:
    static int64_t convertToUnixTimestamp(const struct timeval &v4l2Timestamp) {
        struct timespec systemTime, monotonicTime;

        clock_gettime(CLOCK_REALTIME, &systemTime);

        clock_gettime(CLOCK_MONOTONIC, &monotonicTime);

        int64_t timeDiff = (systemTime.tv_sec - monotonicTime.tv_sec) * 1000000LL +
                           (systemTime.tv_nsec - monotonicTime.tv_nsec) / 1000LL;

        int64_t v4l2MicroSeconds = v4l2Timestamp.tv_sec * 1000000LL + v4l2Timestamp.tv_usec;
        int64_t absoluteMicroSeconds = v4l2MicroSeconds + timeDiff;

        return absoluteMicroSeconds / 1000LL;
    }

    static std::string formatTimestamp2(int64_t unixTimestampMs) {
        using namespace std::chrono;
        system_clock::time_point timePoint = system_clock::time_point(milliseconds(unixTimestampMs));

        time_t tt = system_clock::to_time_t(timePoint);
        std::tm *localTime = std::localtime(&tt);

        char buffer[80];
        strftime(buffer, sizeof(buffer), "%Y-%m-%d %H:%M:%S", localTime);

        int ms = unixTimestampMs % 1000;
        char result[100];
        snprintf(result, sizeof(result), "%s.%03d", buffer, ms);

        return std::string(result);
    }

    static std::string formatTimestamp(int64_t unixTimestampMs) {
        using namespace std::chrono;
        system_clock::time_point timePoint = system_clock::time_point(milliseconds(unixTimestampMs));

        time_t tt = system_clock::to_time_t(timePoint);
        std::tm *localTime = std::localtime(&tt);

        int ms = unixTimestampMs % 1000;

        std::ostringstream oss;
        oss << (localTime->tm_year + 1900) << ','       // 年
            << (localTime->tm_mon + 1) << ','           // 月
            << localTime->tm_mday << ','                // 日
            << localTime->tm_hour << ','                // 时
            << localTime->tm_min << ','                 // 分
            << localTime->tm_sec << ','                 // 秒
            << std::setfill('0') << std::setw(3) << ms; // 毫秒

        return oss.str();
    }
};
